package com.jzo2o.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class SpelUtils {

    private static final Pattern PATTERN = Pattern.compile("(\\#\\{([^\\}]*)\\})");

    /**
     * 将模板中的表达式替换成args参数中的值
     *
     * @param formatter   模板
     * @param paraNameArr 方法对应的参数名称
     * @param args        方法参数值value，用来进行退换对应的表达式
     * @return 模板替换后的字符串
     * <p>
     * 例    format : counter:#{user.id}
     * paraNameAddr [user]
     * args [{"user":{"id":1}}]
     * <p>
     * 转换后结果 -> counter:1
     */
    public static String parse(String formatter, String[] paraNameArr, Object[] args) {
        // 防护性检查
        if (formatter == null) {
            return ""; // 返回空字符串而不是 null
        }

        if (StringUtils.isNotBlank(formatter) && formatter.indexOf("#") > -1) {
            Matcher matcher = PATTERN.matcher(formatter);
            List<String> keys = new ArrayList<>();
            while (matcher.find()) {
                keys.add(matcher.group());
            }

            if (!CollUtils.isEmpty(keys)) {
                ExpressionParser parser = new SpelExpressionParser();
                StandardEvaluationContext context = new StandardEvaluationContext();

                if (paraNameArr != null && args != null) {
                    for (int i = 0; i < paraNameArr.length && i < args.length; i++) {
                        context.setVariable(paraNameArr[i], args[i]);
                    }

                    for (String tmp : keys) {
                        try {
                            String replacement = parser.parseExpression("#" + tmp.substring(2, tmp.length() - 1))
                                    .getValue(context, String.class);
                            if (replacement != null) {
                                formatter = formatter.replace(tmp, replacement);
                            }
                        } catch (Exception e) {
                            log.warn("Failed to parse expression: {}", tmp, e);
                        }
                    }
                }
            }
        }
        return formatter;
    }


}
